import { nodes, links, getPinyinFirstLetters, loadTagifyCDN, initTagify, doMatchGeneric, updateTagifyWhitelist, registerTagifyInstance } from "../globalMgr.js";
import { width, height, updateGraph } from "../graphicsAPI.js";

// 创建节点录入表单
export function createMainForm() {

    const formContainer = d3.select('body').append('div')
        .attr('class', 'node-form-container');

    // 添加展开/收起按钮
    const toggleBtn = formContainer.append('div')
        .attr('class', 'form-toggle-btn')
        .text('+')
        .on('click', function() {
            const isExpanded = formContainer.classed('expanded');
            formContainer.classed('expanded', !isExpanded);
            toggleBtn.text(isExpanded ? '+' : '-');
            // 确保表单显示状态与expanded类同步
            form.style('display', isExpanded ? 'none' : 'block');
            // 强制重新计算布局，确保动画效果
            form.node().getBoundingClientRect();
        });

    // 表单主体
    const form = formContainer.append('div')
        .attr('class', 'node-form')
        .style('display', 'none');
    
    // 创建选项卡
    const tabs = form.append('div')
        .attr('class', 'form-tabs');
    
    const addNodeTab = tabs.append('div')
        .attr('class', 'form-tab active')
        .text('添加节点');
    
    const addConnectionTab = tabs.append('div')
        .attr('class', 'form-tab inactive')
        .text('添加连接')
        .on('click', function() {
            addNodeTab.classed('active', false);
            addConnectionTab.classed('active', true);
            removeNodeTab.classed('active', false);
            removeConnectionTab.classed('active', false);
            addNodeForm.style('display', 'none');
            // 强制隐藏所有移除连接表单
            d3.selectAll('.remove-connection-form-content').style('display', 'none');
            addConnectionForm.style('display', 'block');
            removeNodeForm.style('display', 'none');
            removeConnectionForm.style('display', 'none');
        });
    
    const removeNodeTab = tabs.append('div')
        .attr('class', 'form-tab inactive')
        .text('移除节点')
        .on('click', function() {
            addNodeTab.classed('active', false);
            addConnectionTab.classed('active', false);
            removeNodeTab.classed('active', true);
            removeConnectionTab.classed('active', false);
            addNodeForm.style('display', 'none');
            addConnectionForm.style('display', 'none');
            removeNodeForm.style('display', 'block');
            removeConnectionForm.style('display', 'none');
        });
    
    const removeConnectionTab = tabs.append('div')
        .attr('class', 'form-tab inactive')
        .text('移除连接')
        .on('click', function() {
            addNodeTab.classed('active', false);
            addConnectionTab.classed('active', false);
            removeNodeTab.classed('active', false);
            removeConnectionTab.classed('active', true);
            addNodeForm.style('display', 'none');
            addConnectionForm.style('display', 'none');
            removeNodeForm.style('display', 'none');
            // 强制隐藏所有添加连接表单
            d3.selectAll('.add-connection-form-content').style('display', 'none');
            removeConnectionForm.style('display', 'block');
        });
    
    // 添加节点表单
    const addNodeForm = form.append('div')
        .attr('class', 'node-form-content');
    
    addNodeForm.append('h3').text('添加新节点');
    
    const addNodeFormContent = addNodeForm.append('form');
    
    // 名称输入
    addNodeFormContent.append('label').text('节点名称:').attr('for', 'node-name');
    addNodeFormContent.append('input')
        .attr('type', 'text')
        .attr('id', 'node-name')
        .attr('required', true);
    
    // 描述输入
    // 描述类型选择
    addNodeFormContent.append('label').text('描述类型:').attr('for', 'node-desc-type').style('margin-top', '8px');
    const descTypeSelect = addNodeFormContent.append('select')
        .attr('id', 'node-desc-type')
        .style('margin-bottom', '6px');
    [
        { value: 'plain', label: '纯文本' },
        { value: 'markdown', label: 'Markdown' },
        { value: 'html', label: 'HTML' }
    ].forEach(opt => {
        descTypeSelect.append('option').attr('value', opt.value).text(opt.label);
    });

    // 描述输入区容器
    const descInputContainer = addNodeFormContent.append('div').attr('id', 'desc-input-container');
    // 默认插入 textarea
    let descInput = descInputContainer.append('textarea').attr('id', 'node-desc');

    // 根据desc_type切换输入控件
    descTypeSelect.on('change', function() {
        const type = this.value;
        descInputContainer.html('');
        if (type === 'html') {
            descInput = descInputContainer.append('textarea').attr('id', 'node-desc').attr('placeholder', '支持HTML片段，注意安全');
        } else if (type === 'markdown') {
            descInput = descInputContainer.append('textarea').attr('id', 'node-desc').attr('placeholder', '支持Markdown语法');
        } else {
            descInput = descInputContainer.append('textarea').attr('id', 'node-desc').attr('placeholder', '纯文本');
        }
    });
    
    // 连接节点搜索（带拾取图标）
    addNodeFormContent.append('label').text('连接节点:').attr('for', 'node-connections').style('margin-bottom', '2px');
    const connectionRow = addNodeFormContent.append('div')
        .style('display', 'flex')
        .style('align-items', 'center')
        .style('margin-bottom', '10px')
        .style('gap', '8px');
    const pickIcon1 = connectionRow.append('span')
        .attr('class', 'pick-node-icon')
        .attr('title', '拖拽到节点上拾取')
        .text('+')
        .attr('draggable', true);
    // 只初始化一次 input 和 Tagify
    let addNodeSearch = connectionRow.append('input')
        .attr('type', 'text')
        .attr('id', 'node-connections')
        .attr('required', false)
        .style('flex', '1 1 0%');
    // 节点表单唯一的resultsContainer
    const resultsContainer = addNodeFormContent.append('div')
        .attr('class', 'connection-results')
        .style('display', 'none');
    // 复用节点表单已有的resultsContainer（与连接表单sourceResults/targetResults一致）
    // 已唯一声明resultsContainer，后续直接用该变量
    // --- 修正版：始终只用Tagify，初始化和事件绑定与添加连接表单一致 ---
    function bindCustomInputEvent() {
        let tagifyInstance = addNodeSearch.node()._tagifyInstance;
        function doMatch(searchTerm) {
            const onMatchClick = (node) => {
                tagifyInstance.DOM.input.value = '';
                tagifyInstance.addTags([{ id: node.id, name: node.name }]);
                resultsContainer.style('display', 'none');
                setTimeout(bindCustomInputEvent, 0);
            };
            doMatchGeneric(
                searchTerm,
                tagifyInstance.settings.whitelist,
                (tagifyInstance.value || []).map(item => item.id || item.value),
                onMatchClick,
                resultsContainer,
                getPinyinFirstLetters
            );
        }
        tagifyInstance.off('input').on('input', function(e) {
            const searchTerm = (e.detail.value || '').trim().toLowerCase();
            doMatch(searchTerm);
        });
        // 兼容中文输入法，监听 compositionend 事件
        if (tagifyInstance.DOM && tagifyInstance.DOM.input) {
            tagifyInstance.DOM.input.addEventListener('compositionend', function(e) {
                const val = (e.target && typeof e.target.value === 'string') ? e.target.value.trim().toLowerCase() : '';
                doMatch(val);
            });
        }
    }
    function initTagifyConnection() {
        if (addNodeSearch.node()._tagifyInstance) {
            updateTagifyWhitelist(addNodeSearch.node()._tagifyInstance, nodes);
            return;
        }
        let tagifyConnection = initTagify(addNodeSearch.node(), nodes, {
            maxTags: Infinity
        });
        if (tagifyConnection) {
            addNodeSearch.node()._tagifyInstance = tagifyConnection;
            registerTagifyInstance(addNodeSearch)
            bindCustomInputEvent();
            tagifyConnection.DOM.input.addEventListener('blur', function() {
                setTimeout(() => resultsContainer.style('display', 'none'), 200);
            });
        }
    }
    // 初始化Tagify连接输入框，确保Tagify已加载
    loadTagifyCDN(initTagifyConnection);
    
    // 添加连接表单
    const addConnectionForm = form.append('div')
        .attr('class', 'add-connection-form-content')
        .style('display', 'none');
    
    addConnectionForm.append('h3').text('添加新连接');
    
    // 移除节点表单
    const removeNodeForm = form.append('div')
        .attr('class', 'remove-node-form-content')
        .style('display', 'none');

    removeNodeForm.append('h3').text('移除节点');
    const removeNodeContent = removeNodeForm.append('form');

    // 只创建一个移除连接表单，若已存在则复用
    let removeConnectionForm = d3.select('.remove-connection-form-content');
    if (removeConnectionForm.empty()) {
        removeConnectionForm = form.append('div')
            .attr('class', 'remove-connection-form-content')
            .style('display', 'none');
    }
    

    removeNodeContent.append('label').text('搜索节点:').attr('for', 'remove-node-search').style('margin-bottom', '2px');
    const removeNodeRow = removeNodeContent.append('div')
        .style('display', 'flex')
        .style('align-items', 'center')
        .style('margin-bottom', '10px')
        .style('gap', '8px');
    const pickIcon4 = removeNodeRow.append('span')
        .attr('class', 'pick-node-icon')
        .attr('title', '拖拽到节点上拾取')
        .text('+')
        .attr('draggable', true);
    // 初始化移除节点输入框（参考tagifySourceNode实现）
    const removeNodeSearch = removeNodeRow.append('input')
        .attr('type', 'text')
        .attr('id', 'remove-node-search')
        .attr('required', true)
        .style('flex', '1 1 0%');
    let removeNodeResultsContainer = removeNodeForm.select('.remove-node-results');
    if (removeNodeResultsContainer.empty()) {
        removeNodeResultsContainer = removeNodeForm.append('div')
            .attr('id', 'remove-node-results')
            .attr('class', 'remove-node-results')
            .style('max-height', '150px')
            .style('overflow-y', 'auto')
            .style('display', 'none');
    }
    // Tagify初始化和数据源
    function initTagifyRemoveNode() {
        if (removeNodeSearch.node()._tagifyInstance) {
            updateTagifyWhitelist(removeNodeSearch.node()._tagifyInstance, nodes);
            return;
        }
        let tagifyRemoveNode = initTagify(removeNodeSearch.node(), nodes, {
            maxTags: Infinity
        });
        // 让Tagify实例和input DOM一一对应
        removeNodeSearch.node()._tagifyInstance = tagifyRemoveNode;
        registerTagifyInstance(removeNodeSearch);

        // 实时搜索匹配逻辑
        function doMatchRemoveNode(searchTerm) {
            const onMatchClick = (node) => {
                removeNodeSearch.node()._tagifyInstance.DOM.input.focus();
                removeNodeSearch.node()._tagifyInstance.DOM.input.value = '';
                removeNodeSearch.node()._tagifyInstance.addTags([{ id: node.id, name: node.name }], true);
                removeNodeResultsContainer.style('display', 'none');
            };
            doMatchGeneric(
                searchTerm,
                removeNodeSearch.node()._tagifyInstance.settings.whitelist,
                (removeNodeSearch.node()._tagifyInstance.value || []).map(item => item.id || item.value),
                onMatchClick,
                removeNodeResultsContainer,
                getPinyinFirstLetters
            );
        }
        tagifyRemoveNode.off('input').on('input', function(e) {
            const searchTerm = (e.detail.value || '').trim().toLowerCase();
            doMatchRemoveNode(searchTerm);
        });
        // 兼容中文输入法，监听 compositionend 事件
        if (tagifyRemoveNode.DOM && tagifyRemoveNode.DOM.input) {
            tagifyRemoveNode.DOM.input.addEventListener('compositionend', function(e) {
                const val = (e.target && typeof e.target.value === 'string') ? e.target.value.trim().toLowerCase() : '';
                doMatchRemoveNode(val);
            });
        }
        tagifyRemoveNode.DOM.input.addEventListener('blur', function() {
            setTimeout(() => removeNodeResultsContainer.style('display', 'none'), 200);
        });
        
        // 重新绑定节点拾取器功能
        if (window.__bindNodePickDrop) window.__bindNodePickDrop();
    }
    loadTagifyCDN(initTagifyRemoveNode);

    // 只保留一个移除节点按钮，缩小尺寸
    removeNodeContent.selectAll('button').remove();
    removeNodeContent.append('button')
        .attr('type', 'button')
        .text('移除节点')
        .attr('class', 'remove-button')
        .on('click', async function() {
            if (!removeNodeSearch.node()._tagifyInstance) return;
            const selectedNodes = removeNodeSearch.node()._tagifyInstance.value;
            if (!selectedNodes.length) {
                alert('请通过输入或拾取选择要移除的节点');
                return;
            }
            // 兼容Tagify的value结构，优先用id，没有就用value
            const ids = selectedNodes.map(item => item.id || item.value);
            // 始终显示节点名称，无名用“未命名节点(ID:xxx)”
            function getNodeDisplayName(id) {
                const n = nodes.find(nd => nd.id === Number(id));
                if (n) {
                    if (n.name && n.name.trim()) return n.name;
                    return `未命名节点(ID:${n.id})`;
                }
                return `未知节点(ID:${id})`;
            }
            const names = ids.map(getNodeDisplayName);
            const confirmRemove = confirm(`确定要移除以下节点吗？\n${names.join(', ')}\n这将同时移除所有相关连接！`);
            if (confirmRemove) {
                let failedIds = [];
                let failReasons = {};
                for (const id of ids) {
                    try {
                        const result = await NetworkAPI.removeNode(id);
                        if (!result) {
                            failedIds.push(id);
                            failReasons[id] = `API返回:${result}`;
                        }
                    } catch (e) {
                        failedIds.push(id);
                        failReasons[id] = e && e.stack ? e.stack : (e ? e.toString() : '未知异常');
                    }
                }
                // 强制刷新数据和视图
                if (typeof window.updateGraph === 'function') {
                    window.updateGraph();
                }
                if (failedIds.length === 0) {
                    removeNodeSearch.node()._tagifyInstance.removeAllTags();
                    if (typeof initTagifyConnection === 'function') {
                        initTagifyConnection();
                    }
                    if (typeof initTagifySourceNode === 'function') {
                        initTagifySourceNode();
                    }
                    if (typeof initTagifyTargetNode === 'function') {
                        initTagifyTargetNode();
                    }
                    alert('节点已成功移除');
                } else {
                    const failedNames = failedIds.map(getNodeDisplayName);
                    alert('部分节点移除失败：' + failedNames.join(', '));
                    console.error('节点移除失败', failedNames, failReasons);
                }
            }
        });
    removeConnectionForm.append('label').text('源节点:').attr('for', 'remove-source-node').style('margin-bottom', '2px');
    const removeSourceRow = removeConnectionForm.append('div')
        .style('display', 'flex')
        .style('align-items', 'center')
        .style('margin-bottom', '10px')
        .style('gap', '8px');
    const pickIcon5 = removeSourceRow.append('span')
        .attr('class', 'pick-node-icon')
        .attr('title', '拖拽到节点上拾取')
        .text('+')
        .attr('draggable', true);
    // 源节点Tagify输入框
    const removeSourceSearch = removeSourceRow.append('input')
        .attr('type', 'text')
        .attr('id', 'remove-source-node')
        .attr('required', true)
        .style('flex', '1 1 0%');
    let removeSourceResults = removeConnectionForm.select('.remove-connection-results');
    if (removeSourceResults.empty()) {
        removeSourceResults = removeConnectionForm.append('div')
            .attr('class', 'remove-connection-results')
            .style('max-height', '150px')
            .style('overflow-y', 'auto')
            .style('display', 'none')
            .style('margin-bottom', '10px');
    }
    function initTagifyRemoveSourceNode() {
        if (removeSourceSearch.node()._tagifyInstance) {
            updateTagifyWhitelist(removeSourceSearch.node()._tagifyInstance, nodes);
            return;
        }
        let tagifyRemoveSourceNode = initTagify(removeSourceSearch.node(), nodes, {
            maxTags: 1
        });
        removeSourceSearch.node()._tagifyInstance = tagifyRemoveSourceNode;
        registerTagifyInstance(removeSourceSearch);

        function doMatchRemoveSourceNode(searchTerm) {
            let tagifyInst = removeSourceSearch.node()._tagifyInstance;
            const onMatchClick = (node) => {
                tagifyInst.DOM.input.focus();
                tagifyInst.DOM.input.value = '';
                tagifyInst.removeAllTags();
                tagifyInst.addTags([{ id: node.id, name: node.name }]);
                removeSourceResults.style('display', 'none');
                d3.select('#remove-source-node')
                    .attr('data-node-id', node.id)
                    .attr('title', `ID: ${node.id}`);
            };
            doMatchGeneric(
                searchTerm,
                tagifyInst.settings.whitelist,
                (tagifyInst.value || []).map(item => item.id || item.value),
                onMatchClick,
                removeSourceResults,
                getPinyinFirstLetters
            );
        }
        tagifyRemoveSourceNode.off('input').on('input', function(e) {
            const searchTerm = (e.detail.value || '').trim().toLowerCase();
            doMatchRemoveSourceNode(searchTerm);
        });
        if (tagifyRemoveSourceNode.DOM && tagifyRemoveSourceNode.DOM.input) {
            tagifyRemoveSourceNode.DOM.input.addEventListener('compositionend', function(e) {
                const val = (e.target && typeof e.target.value === 'string') ? e.target.value.trim().toLowerCase() : '';
                doMatchRemoveSourceNode(val);
            });
        }
        tagifyRemoveSourceNode.DOM.input.addEventListener('blur', function() {
            setTimeout(() => removeSourceResults.style('display', 'none'), 200);
        });
        // 重新绑定节点拾取器功能
        if (window.__bindNodePickDrop) window.__bindNodePickDrop();
    }
    loadTagifyCDN(initTagifyRemoveSourceNode);

    // 目标节点搜索（带拾取图标）
    removeConnectionForm.append('label').text('目标节点:').attr('for', 'remove-target-node').style('margin-bottom', '2px');
    const removeTargetRow = removeConnectionForm.append('div')
        .style('display', 'flex')
        .style('align-items', 'center')
        .style('margin-bottom', '10px')
        .style('gap', '8px');
    const pickIcon6 = removeTargetRow.append('span')
        .attr('class', 'pick-node-icon')
        .attr('title', '拖拽到节点上拾取')
        .text('+')
        .attr('draggable', true);
    // 目标节点Tagify输入框
    const removeTargetSearch = removeTargetRow.append('input')
        .attr('type', 'text')
        .attr('id', 'remove-target-node')
        .attr('required', true)
        .style('flex', '1 1 0%');
    let removeTargetResults = removeConnectionForm.selectAll('.remove-connection-results').nodes()[1] ? d3.select(removeConnectionForm.selectAll('.remove-connection-results').nodes()[1]) : null;
    if (!removeTargetResults) {
        removeTargetResults = removeConnectionForm.append('div')
            .attr('class', 'remove-connection-results')
            .style('max-height', '150px')
            .style('overflow-y', 'auto')
            .style('display', 'none');
    }
    function initTagifyRemoveTargetNode() {
        if (removeTargetSearch.node()._tagifyInstance) {
            updateTagifyWhitelist(removeTargetSearch.node()._tagifyInstance, nodes);
            return;
        }
        let tagifyRemoveTargetNode = initTagify(removeTargetSearch.node(), nodes, {
            maxTags: 1
        });
        removeTargetSearch.node()._tagifyInstance = tagifyRemoveTargetNode;
        registerTagifyInstance(removeTargetSearch);
        function doMatchRemoveTargetNode(searchTerm) {
            let tagifyInst = removeTargetSearch.node()._tagifyInstance;
            const onMatchClick = (node) => {
                tagifyInst.DOM.input.focus();
                tagifyInst.DOM.input.value = '';
                tagifyInst.removeAllTags();
                tagifyInst.addTags([{ id: node.id, name: node.name }]);
                removeTargetResults.style('display', 'none');
                d3.select('#remove-target-node')
                    .attr('data-node-id', node.id)
                    .attr('title', `ID: ${node.id}`);
            };
            doMatchGeneric(
                searchTerm,
                tagifyInst.settings.whitelist,
                (tagifyInst.value || []).map(item => item.id || item.value),
                onMatchClick,
                removeTargetResults,
                getPinyinFirstLetters
            );
        }
        tagifyRemoveTargetNode.off('input').on('input', function(e) {
            const searchTerm = (e.detail.value || '').trim().toLowerCase();
            doMatchRemoveTargetNode(searchTerm);
        });
        if (tagifyRemoveTargetNode.DOM && tagifyRemoveTargetNode.DOM.input) {
            tagifyRemoveTargetNode.DOM.input.addEventListener('compositionend', function(e) {
                const val = (e.target && typeof e.target.value === 'string') ? e.target.value.trim().toLowerCase() : '';
                doMatchRemoveTargetNode(val);
            });
        }
        tagifyRemoveTargetNode.DOM.input.addEventListener('blur', function() {
            setTimeout(() => removeTargetResults.style('display', 'none'), 200);
        });
        // 重新绑定节点拾取器功能
        if (window.__bindNodePickDrop) window.__bindNodePickDrop();
    }
    loadTagifyCDN(initTagifyRemoveTargetNode);

    // 搜索结果容器
    // ...已唯一声明removeSourceResults和removeTargetResults，复用即可...


    // 提交按钮
    removeConnectionForm.append('button')
        .attr('type', 'button')
        .text('移除连接')
        .attr('class', 'remove-button')
        .on('click', function() {
            const sourceId = Number(d3.select('#remove-source-node').attr('data-node-id'));
            const targetId = Number(d3.select('#remove-target-node').attr('data-node-id'));

            if (!sourceId || !targetId) {
                alert('请通过下拉菜单选择有效的源节点和目标节点');
                return;
            }

            const sourceNode = nodes.find(n => n.id === sourceId);
            const targetNode = nodes.find(n => n.id === targetId);
            const confirmRemove = confirm(`确定要移除连接 "${sourceNode?.name || sourceId}" → "${targetNode?.name || targetId}" 吗？`);

            if (confirmRemove) {
                const success = NetworkAPI.removeConnection(sourceId, targetId);
                if (success) {
                    if (removeSourceSearch.node()._tagifyInstance) removeSourceSearch.node()._tagifyInstance.removeAllTags();
                    if (removeTargetSearch.node()._tagifyInstance) removeTargetSearch.node()._tagifyInstance.removeAllTags();
                    // 移除前端内存中的连接
                    const idx = links.findIndex(l =>
                        ((l.source.id ?? l.source) == sourceId && (l.target.id ?? l.target) == targetId) ||
                        ((l.source.id ?? l.source) == targetId && (l.target.id ?? l.target) == sourceId)
                    );
                    if (idx !== -1) links.splice(idx, 1);

                    // 刷新图形
                    if (typeof updateGraph === 'function') updateGraph();
                    if (window.simulation) {
                        if (typeof window.simulation.nodes === 'function') window.simulation.nodes(nodes);
                        if (typeof window.simulation.force === 'function') {
                            const linkForce = window.simulation.force('link');
                            if (linkForce && typeof linkForce.links === 'function') linkForce.links(links);
                        }
                        if (typeof window.simulation.alpha === 'function') window.simulation.alpha(1).restart();
                    }
                    alert('连接已成功移除');
                } else {
                    // 新增节点后，移除连接表单的Tagify输入框也应刷新whitelist
                    if (typeof initTagifyRemoveSourceNode === 'function') initTagifyRemoveSourceNode();
                    if (typeof initTagifyRemoveTargetNode === 'function') initTagifyRemoveTargetNode();
                    alert('移除连接失败，请检查连接是否存在');
                }
            }
        });

    const addConnectionFormContent = addConnectionForm.append('form');

    // 源节点搜索（带拾取图标）
    addConnectionFormContent.append('label').text('源节点:').attr('for', 'source-node').style('margin-bottom', '2px');
    const addSourceRow = addConnectionFormContent.append('div')
        .style('display', 'flex')
        .style('align-items', 'center')
        .style('margin-bottom', '10px')
        .style('gap', '8px');
    const pickIcon2 = addSourceRow.append('span')
        .attr('class', 'pick-node-icon')
        .attr('title', '拖拽到节点上拾取')
        .text('+')
        .attr('draggable', true);
    // 源节点Tagify输入框
    const addSourceSearch = addSourceRow.append('input')
        .attr('type', 'text')
        .attr('id', 'source-node')
        .attr('required', true)
        .style('flex', '1 1 0%');
    let sourceResults = addConnectionFormContent.select('.add-connection-results');
    if (sourceResults.empty()) {
        sourceResults = addConnectionFormContent.append('div')
            .attr('class', 'add-connection-results')
            .style('max-height', '150px')
            .style('overflow-y', 'auto')
            .style('display', 'none')
            .style('margin-bottom', '10px');
    }
    function initTagifySourceNode() {
        if (addSourceSearch.node()._tagifyInstance) {
            updateTagifyWhitelist(addSourceSearch.node()._tagifyInstance, nodes);
            return;
        }
        let tagifySourceNode = initTagify(addSourceSearch.node(), nodes, {
            maxTags: 1
        });
        addSourceSearch.node()._tagifyInstance = tagifySourceNode;
        registerTagifyInstance(addSourceSearch);
        function doMatchSourceNode(searchTerm) {
            let tagifyInst = addSourceSearch.node()._tagifyInstance;
            const onMatchClick = (node) => {
                tagifyInst.DOM.input.focus();
                tagifyInst.DOM.input.value = '';
                tagifyInst.removeAllTags();
                tagifyInst.addTags([{ id: node.id, name: node.name }]);
                sourceResults.style('display', 'none');
                d3.select('#source-node')
                    .attr('data-node-id', node.id)
                    .attr('title', `ID: ${node.id}`);
            };
            doMatchGeneric(
                searchTerm,
                tagifyInst.settings.whitelist,
                (tagifyInst.value || []).map(item => item.id || item.value),
                onMatchClick,
                sourceResults,
                getPinyinFirstLetters
            );
        }
        tagifySourceNode.off('input').on('input', function(e) {
            const searchTerm = (e.detail.value || '').trim().toLowerCase();
            doMatchSourceNode(searchTerm);
        });
        if (tagifySourceNode.DOM && tagifySourceNode.DOM.input) {
            tagifySourceNode.DOM.input.addEventListener('compositionend', function(e) {
                const val = (e.target && typeof e.target.value === 'string') ? e.target.value.trim().toLowerCase() : '';
                doMatchSourceNode(val);
            });
        }
        tagifySourceNode.DOM.input.addEventListener('blur', function() {
            setTimeout(() => sourceResults.style('display', 'none'), 200);
        });
        // 移除对旧拾取机制的调用
    }
    loadTagifyCDN(initTagifySourceNode);

    // 目标节点搜索（带拾取图标）
    addConnectionFormContent.append('label').text('目标节点:').attr('for', 'target-node').style('margin-bottom', '2px');
    const addTargetRow = addConnectionFormContent.append('div')
        .style('display', 'flex')
        .style('align-items', 'center')
        .style('margin-bottom', '10px')
        .style('gap', '8px');
    const pickIcon3 = addTargetRow.append('span')
        .attr('class', 'pick-node-icon')
        .attr('title', '拖拽到节点上拾取')
        .text('+')
        .attr('draggable', true);
    // 目标节点Tagify输入框
    const addTargetSearch = addTargetRow.append('input')
        .attr('type', 'text')
        .attr('id', 'target-node')
        .attr('required', true)
        .style('flex', '1 1 0%');
    let targetResults = addConnectionFormContent.selectAll('.add-connection-results').nodes()[1] ? d3.select(addConnectionFormContent.selectAll('.add-connection-results').nodes()[1]) : null;
    if (!targetResults) {
        targetResults = addConnectionFormContent.append('div')
            .attr('class', 'add-connection-results')
            .style('max-height', '150px')
            .style('overflow-y', 'auto')
            .style('display', 'none');
    }
    function initTagifyTargetNode() {
        if (addTargetSearch.node()._tagifyInstance) {
            updateTagifyWhitelist(addTargetSearch.node()._tagifyInstance, nodes);
            return;
        }
        let tagifyTargetNode = initTagify(addTargetSearch.node(), nodes, {
            maxTags: 1
        });
        addTargetSearch.node()._tagifyInstance = tagifyTargetNode;
        registerTagifyInstance(addTargetSearch);
        function doMatchTargetNode(searchTerm) {
            let tagifyInst = addTargetSearch.node()._tagifyInstance;
            const onMatchClick = (node) => {
                tagifyInst.DOM.input.focus();
                tagifyInst.DOM.input.value = '';
                tagifyInst.removeAllTags();
                tagifyInst.addTags([{ id: node.id, name: node.name }]);
                targetResults.style('display', 'none');
                d3.select('#target-node')
                    .attr('data-node-id', node.id)
                    .attr('title', `ID: ${node.id}`);
            };
            doMatchGeneric(
                searchTerm,
                tagifyInst.settings.whitelist,
                (tagifyInst.value || []).map(item => item.id || item.value),
                onMatchClick,
                targetResults,
                getPinyinFirstLetters
            );
        }
        tagifyTargetNode.off('input').on('input', function(e) {
            const searchTerm = (e.detail.value || '').trim().toLowerCase();
            doMatchTargetNode(searchTerm);
        });
        if (tagifyTargetNode.DOM && tagifyTargetNode.DOM.input) {
            tagifyTargetNode.DOM.input.addEventListener('compositionend', function(e) {
                const val = (e.target && typeof e.target.value === 'string') ? e.target.value.trim().toLowerCase() : '';
                doMatchTargetNode(val);
            });
        }
        tagifyTargetNode.DOM.input.addEventListener('blur', function() {
            setTimeout(() => targetResults.style('display', 'none'), 200);
        });
        // 移除对旧拾取机制的调用
    }
    loadTagifyCDN(initTagifyTargetNode);
    
    // 切换回节点表单
    addNodeTab.on('click', function() {
        addConnectionTab.classed('active', false);
        addNodeTab.classed('active', true);
        removeNodeTab.classed('active', false);
        removeConnectionTab.classed('active', false);
        addConnectionForm.style('display', 'none');
        addNodeForm.style('display', 'block');
        removeNodeForm.style('display', 'none');
        removeConnectionForm.style('display', 'none');
    });
    

    // 拾取图标拖拽逻辑（必须在所有 pickIcon/input 定义后）
    const pickIconMap = [
        { icon: pickIcon1, input: addNodeSearch },
        { icon: pickIcon2, input: addSourceSearch },
        { icon: pickIcon3, input: addTargetSearch },
        { icon: pickIcon4, input: removeNodeSearch },
        { icon: pickIcon5, input: removeSourceSearch },
        { icon: pickIcon6, input: removeTargetSearch },
    ];

    // 创建一个更稳健的节点拾取器系统
    class NodePickerManager {
        constructor() {
            this.pickers = new Map();
            this.activePicker = null;
            this.initGlobalEvents();
        }

        // 初始化全局事件监听器
        initGlobalEvents() {
            // 监听节点更新事件
            window.addEventListener('nodesUpdated', () => {
                this.bindAllNodes();
            });

            // 监听拖拽开始事件
            pickIconMap.forEach(({icon, input}) => {
                icon.on('dragstart', (event) => {
                    event.dataTransfer.setData('text/plain', '__pick_node__');
                    this.activePicker = input;
                    icon.classed('dragging', true);
                });

                icon.on('dragend', () => {
                    icon.classed('dragging', false);
                    this.activePicker = null;
                });
            });
        }

        // 绑定所有节点的拾取事件
        bindAllNodes() {
            d3.selectAll('.node-group')
                .attr('draggable', true)
                .on('dragstart.nodePicker', null)
                .on('dragend.nodePicker', null)
                .on('dragover.nodePicker', null)
                .on('drop.nodePicker', null);

            d3.selectAll('.node-group')
                .on('dragover.nodePicker', (event) => {
                    event.preventDefault();
                })
                .on('drop.nodePicker', (event, d) => {
                    event.preventDefault();
                    if (this.activePicker && event.dataTransfer.getData('text/plain') === '__pick_node__') {
                        this.pickNode(d, this.activePicker);
                    }
                });
        }

        // 拾取节点
        pickNode(nodeData, inputElement) {
            const nodeName = nodeData.name || nodeData.id;
            const nodeId = nodeData.id;
            // 设置输入框的值和属性
            // inputElement.property('value', nodeName)
            inputElement
                .attr('data-node-id', nodeId)
                .attr('title', `ID: ${nodeId}`);

            console.log(`[NodePicker] Picked node: ${nodeName} (ID: ${nodeId})`);

            // 直接通过input DOM获取Tagify实例
            const tagifyInstance = inputElement.node()._tagifyInstance;
            if (tagifyInstance) {
                const isMulti = tagifyInstance.settings.maxTags > 1 || tagifyInstance.settings.maxTags === Infinity;
                if (isMulti) {
                    // 多选时追加标签（如果不存在，类型安全判断）
                    const exists = tagifyInstance.value.some(item => String(item.id ?? item.value) === String(nodeId));
                    if (!exists) {
                        tagifyInstance.addTags([{ id: nodeId, name: nodeName }], true);
                        }
                    } else {
                        // 单选时清空再添加
                        tagifyInstance.removeAllTags();
                        tagifyInstance.addTags([{ id: nodeId, name: nodeName }]);
                    }
            }
        }

        // 初始化系统
        init() {
            this.bindAllNodes();
            console.log('[NodePicker] Initialized');
        }
    }

    // 创建全局节点拾取器管理器实例
    window.nodePickerManager = new NodePickerManager();

    // 初始化节点拾取器
    window.nodePickerManager.init();

    // 暴露给全局，供 updateGraph 调用
    window.__bindNodePickDrop = () => {
        window.nodePickerManager.bindAllNodes();
    };
    
    // 节点表单已选连接显示
    // 移除原有的selectedConnections逻辑，全部由Tagify管理
    
    // 节点表单提交按钮
    addNodeFormContent.append('button')
        .attr('type', 'button')
        .text('添加节点')
        .attr('class', 'form-button')
        .on('click', async function() {
            const name = d3.select('#node-name').property('value');
            const description = d3.select('#node-desc').property('value');
            const descType = d3.select('#node-desc-type').property('value') || 'plain';
            if (!name) {
                alert('请输入节点名称');
                return;
            }
            // 获取所有被选中的连接节点id
            let connIds = [];
            if (addNodeSearch.node()._tagifyInstance && Array.isArray(addNodeSearch.node()._tagifyInstance.value)) {
                connIds = addNodeSearch.node()._tagifyInstance.value.map(item => Number(item.id ?? item.value));
            }
            // 计算新节点初始位置：如有多个连接节点，取所有连接节点坐标平均值，否则随机
            let initX = Math.random() * width;
            let initY = Math.random() * height;
            if (connIds.length > 0) {
                let sumX = 0, sumY = 0, count = 0;
                connIds.forEach(cid => {
                    const n = nodes.find(nn => nn.id == cid);
                    if (n && typeof n.x === 'number' && typeof n.y === 'number') {
                        sumX += n.x;
                        sumY += n.y;
                        count++;
                    }
                });
                if (count > 0) {
                    initX = sumX / count;
                    initY = sumY / count;
                }
            }
            // 添加节点，传递期望位置
            const newNode = await NetworkAPI.addNode(name, description, connIds, initX, initY, descType);
            // 前端内存同步添加所有新连接，保证视图一致（source/target 只用 id 字符串）
            if (newNode && newNode.id && Array.isArray(connIds) && connIds.length > 0) {
                connIds.forEach(cid => {
                    const cidNum = Number(cid);
                    if (!links.some(l => (Number(l.source?.id ?? l.source) === newNode.id && Number(l.target?.id ?? l.target) === cidNum)
                        || (Number(l.source?.id ?? l.source) === cidNum && Number(l.target?.id ?? l.target) === newNode.id))) {
                        links.push({ source: newNode.id, target: cidNum, weight: 1 });
                    }
                });
            }
            if (typeof updateGraph === 'function') updateGraph();
            // 保证 simulation 节点和连接数据同步
            if (window.simulation) {
                if (typeof window.simulation.nodes === 'function') window.simulation.nodes(nodes);
                if (typeof window.simulation.force === 'function') {
                    const linkForce = window.simulation.force('link');
                    if (linkForce && typeof linkForce.links === 'function') linkForce.links(links);
                }
                if (typeof window.simulation.alpha === 'function') window.simulation.alpha(1).restart();
            }
            // 重置表单
            d3.select('#node-name').property('value', '');
            d3.select('#node-desc').property('value', '');
            if (addNodeSearch.node()._tagifyInstance) addNodeSearch.node()._tagifyInstance.removeAllTags();
            // 新节点添加后，刷新移除节点表单和连接表单的Tagify数据源，保证可搜索和可拾取
            if (typeof initTagifyRemoveNode === 'function') {
                initTagifyRemoveNode();
            }
            if (typeof initTagifySourceNode === 'function') {
                initTagifySourceNode();
            }
            if (typeof initTagifyTargetNode === 'function') {
                initTagifyTargetNode();
            }
        });
    // 连接表单提交按钮
    addConnectionFormContent.append('button')
        .attr('type', 'button')
        .text('添加连接')
        .attr('class', 'form-button')
        .on('click', async function() {
            const button = d3.select(this);
            const originalText = button.text();
            button.text('处理中...').attr('disabled', true);

            const sourceId = Number(d3.select('#source-node').attr('data-node-id'));
            const targetId = Number(d3.select('#target-node').attr('data-node-id'));

            if (!sourceId || !targetId) {
                alert('请通过下拉菜单选择有效的源节点和目标节点');
                button.text(originalText).attr('disabled', null); // 修复：移除disabled属性
                return;
            }

            if (sourceId === targetId) {
                alert('不能连接节点到自身');
                button.text(originalText).attr('disabled', null); // 修复：移除disabled属性
                return;
            }

            const sourceNode = nodes.find(n => n.id === sourceId);
            const targetNode = nodes.find(n => n.id === targetId);

            console.groupCollapsed('[UI] Creating connection');
            console.info('Source:', sourceNode ? sourceNode.name : sourceId);
            console.info('Target:', targetNode ? targetNode.name : targetId);

            try {
                const success = await NetworkAPI.addConnection(sourceId, targetId);

                if (success) {
                    console.info('Connection created successfully');
                    d3.select('#source-node').property('value', '').attr('data-node-id', '');
                    d3.select('#target-node').property('value', '').attr('data-node-id', '');
                    sourceResults.style('display', 'none');
                    targetResults.style('display', 'none');

                    // 显示成功提示
                    const successMsg = `成功创建连接: ${sourceNode?.name || sourceId} → ${targetNode?.name || targetId}`;
                    console.info(successMsg);
                    alert(successMsg);
                } else {
                    const errorMsg = '创建连接失败，请检查节点是否存在或连接是否已存在';
                    console.warn(errorMsg);
                    alert(errorMsg);
                }
            } catch (error) {
                console.error('Error creating connection:', error);
                alert('创建连接时发生错误: ' + error.message);
            } finally {
                button.text(originalText).attr('disabled', null); // 修复：移除disabled属性
                console.groupEnd();
            }
        });
}